package com.liyuxiang.graph.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.concurrent.CompletableFuture;

@Service
public class IntentRecognitionService {
    
    private static final Logger logger = LoggerFactory.getLogger(IntentRecognitionService.class);
    private final ChatClient chatClient;
    private final ObjectMapper objectMapper;
    
    @Autowired
    private AiCacheService cacheService;
    
    @Autowired
    private PerformanceMonitorService performanceMonitor;
    
    // AI智能意图识别提示词 - 完全依赖AI判断，支持上下文感知和直接推荐科室
    private static final String INTENT_ANALYSIS_PROMPT = """
            你是专业的医疗意图识别AI助手。请智能分析用户的医疗咨询意图。
            
            用户输入: {query}
            对话上下文: {conversationContext}
            当前对话阶段: {conversationStage}
            历史问题数: {questionCount}
            
            请智能判断用户意图：
            - 有意图: 用户描述身体症状、健康问题、求医建议等
            - 无意图: 打招呼、功能询问、闲聊、测试、无关话题等
            - 直接挂号: 用户明确询问科室挂号，如"头疼挂哪个科"、"胃痛挂什么科"等
            
            请特别注意：
            1. 识别用户是否直接询问科室挂号（如："头疼挂哪个科"、"胃痛看什么科"）
            2. 同样的词语在不同上下文中意图可能不同
            3. 考虑对话的连续性和发展阶段
            4. 区分真实症状描述和闲聊测试
            5. 评估用户输入的医疗相关性和紧急程度
            6. 根据对话历史判断用户的真实意图
            7. 如果用户明确询问挂号，应该跳过症状收集直接推荐科室
            
            返回JSON格式：
            {
              "intent": "有意图/无意图/直接挂号",
              "confidence": 0.0-1.0,
              "reason": "基于上下文的详细判断理由",
              "keywords": ["识别到的关键词"],
              "medicalTerms": ["医疗相关术语"],
              "riskLevel": "emergency/high/medium/low",
              "conversationStage": "initial/symptom_inquiry/detail_collection/assessment/direct_recommendation",
              "nextAction": "建议的下一步行动",
              "shouldSkipSymptomCollection": false,
              "directRecommendation": false
            }
            """;
    
    public IntentRecognitionService(@Qualifier("simpleCharClientBuilder") ChatClient.Builder simpleCharClientBuilder, ObjectMapper objectMapper) {
        this.chatClient = simpleCharClientBuilder.build();
        this.objectMapper = objectMapper;
    }
    
    public IntentAnalysisResult analyzeIntent(String query, List<String> conversationHistory, String userId) {
        return analyzeIntent(query, conversationHistory, userId, "", 0);
    }
    
    /**
     * 智能意图识别 - 支持上下文感知，完全基于AI判断
     */
    public IntentAnalysisResult analyzeIntent(String query, List<String> conversationHistory, 
                                            String userId, String conversationStage, int questionCount) {
        long startTime = System.currentTimeMillis();
        logger.info("开始AI意图识别 - 用户ID: {}, 输入: {}, 阶段: {}, 问题数: {}", 
                   userId, query, conversationStage, questionCount);
        
        // 直接检测常见的挂号询问模式
        if (isDirectDepartmentInquiry(query)) {
            logger.info("检测到直接科室询问 - 用户ID: {}, 查询: {}", userId, query);
            return createDirectInquiryResult(query, userId);
        }
        
        // 构建对话上下文
        String conversationContext = buildConversationContext(conversationHistory);
        
        // 检查缓存（包含上下文）
        IntentAnalysisResult cachedResult = cacheService.getIntentCache(
            query, userId, conversationContext + conversationStage, IntentAnalysisResult.class);
        if (cachedResult != null) {
            long duration = System.currentTimeMillis() - startTime;
            logger.info("意图识别缓存命中 - 用户ID: {}, 耗时: {}ms", userId, duration);
            return cachedResult;
        }
        
        try {
            // 构建智能提示词
            String prompt = INTENT_ANALYSIS_PROMPT
                    .replace("{query}", query)
                    .replace("{conversationContext}", conversationContext)
                    .replace("{conversationStage}", conversationStage)
                    .replace("{questionCount}", String.valueOf(questionCount));
            
            logger.info("发送AI智能分析请求 - 用户ID: {}", userId);
            
            String aiResponse = chatClient.prompt()
                    .user(prompt)
                    .call()
                    .content();
            
            IntentAnalysisResult result = parseAiResponse(aiResponse);
            
            // 缓存结果（包含上下文）
            cacheService.setIntentCache(query, userId, conversationContext + conversationStage, result);
            
            long duration = System.currentTimeMillis() - startTime;
            logger.info("AI意图识别完成 - 用户ID: {}, 意图: {}, 置信度: {}, 耗时: {}ms", 
                       userId, result.getIntent(), result.getConfidence(), duration);
            
            return result;
            
        } catch (Exception e) {
            logger.error("AI意图识别失败 - 用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            return createMinimalFallback(query, userId);
        }
    }

    /**
     * 异步分析意图 - 用于非阻塞调用
     */
    @Async("aiTaskExecutor")
    public CompletableFuture<IntentAnalysisResult> analyzeIntentAsync(String query, List<String> conversationHistory, String userId) {
        return CompletableFuture.completedFuture(analyzeIntent(query, conversationHistory, userId));
    }
    
    private IntentAnalysisResult parseAiResponse(String response) {
        try {
            int startIndex = response.indexOf('{');
            int endIndex = response.lastIndexOf('}') + 1;
            
            if (startIndex >= 0 && endIndex > startIndex) {
                String jsonStr = response.substring(startIndex, endIndex);
                JsonNode jsonNode = objectMapper.readTree(jsonStr);
                
                String intent = jsonNode.get("intent").asText("无意图");
                double confidence = jsonNode.get("confidence").asDouble(0.5);
                String reason = jsonNode.get("reason").asText("AI智能分析结果");
                String[] keywords = objectMapper.convertValue(
                    jsonNode.get("keywords") != null ? jsonNode.get("keywords") : objectMapper.createArrayNode(), 
                    String[].class);
                String[] medicalTerms = objectMapper.convertValue(
                    jsonNode.get("medicalTerms") != null ? jsonNode.get("medicalTerms") : objectMapper.createArrayNode(), 
                    String[].class);
                String riskLevel = jsonNode.get("riskLevel").asText("low");
                
                // 支持新增的字段
                String conversationStage = jsonNode.has("conversationStage") ? 
                    jsonNode.get("conversationStage").asText("") : "";
                String nextAction = jsonNode.has("nextAction") ? 
                    jsonNode.get("nextAction").asText("") : "";
                boolean shouldSkipSymptomCollection = jsonNode.has("shouldSkipSymptomCollection") ? 
                    jsonNode.get("shouldSkipSymptomCollection").asBoolean(false) : false;
                boolean directRecommendation = jsonNode.has("directRecommendation") ? 
                    jsonNode.get("directRecommendation").asBoolean(false) : false;
                
                return new ExtendedIntentAnalysisResult(intent, confidence, reason, keywords, 
                                                       medicalTerms, riskLevel, true, conversationStage, nextAction,
                                                       shouldSkipSymptomCollection, directRecommendation);
            }
        } catch (Exception e) {
            logger.warn("解析AI响应JSON失败: {}", e.getMessage());
        }
        
        logger.info("使用简单文本解析作为备用方案");
        return createSimpleAiResult(response);
    }
    
    /**
     * 简单AI结果解析 - 作为备用方案
     */
    private IntentAnalysisResult createSimpleAiResult(String response) {
        String lowerResponse = response.toLowerCase();
        String intent;
        double confidence;
        String reason;
        
        // 基于响应内容的简单判断
        if (lowerResponse.contains("有意图") || lowerResponse.contains("medical") || 
            lowerResponse.contains("症状") || lowerResponse.contains("医疗")) {
            intent = "有意图";
            confidence = 0.7;
            reason = "AI响应中包含医疗相关关键词";
        } else {
            intent = "无意图";
            confidence = 0.6;
            reason = "AI响应未检测到明确医疗意图";
        }
        
        return new IntentAnalysisResult(intent, confidence, reason, new String[]{}, new String[]{}, "low", false);
    }
    
    /**
     * 最小化备用分析 - 只在AI完全失败时使用
     */
    private IntentAnalysisResult createMinimalFallback(String query, String userId) {
        logger.warn("使用最小化备用分析 - 用户ID: {}, AI服务不可用", userId);
        
        // 非常简单的备用逻辑，只做最基本的判断
        String intent = "无意图"; // 保守策略，默认无意图
        double confidence = 0.3; // 低置信度表示不确定
        String reason = "AI服务不可用，使用备用逻辑";
        
        return new IntentAnalysisResult(intent, confidence, reason, 
                                      new String[]{query}, new String[]{}, "low", false);
    }
    
    /**
     * 构建对话上下文摘要
     */
    private String buildConversationContext(List<String> conversationHistory) {
        if (conversationHistory == null || conversationHistory.isEmpty()) {
            return "无对话历史";
        }
        
        // 取最后3轮对话作为上下文
        int start = Math.max(0, conversationHistory.size() - 6); // 3轮 = 6条消息
        List<String> recentHistory = conversationHistory.subList(start, conversationHistory.size());
        
        StringBuilder context = new StringBuilder();
        for (String message : recentHistory) {
            context.append(message).append("\n");
        }
        
        return context.toString().trim();
    }
    
    /**
     * 直接检测是否是科室询问
     */
    private boolean isDirectDepartmentInquiry(String query) {
        String lowerQuery = query.toLowerCase();
        // 检测关键模式
        String[] patterns = {
            "挂什么科", "挂哪个科", "看什么科", "看哪个科", 
            "什么科室", "哪个科室", "挂号科室", "就诊科室",
            "头疼挂", "头痛挂", "胃痛挂", "腹痛挂", "胸痛挂",
            "发烧挂", "咳嗽挂", "感冒挂", "腰痛挂"
        };
        
        for (String pattern : patterns) {
            if (lowerQuery.contains(pattern)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * 为直接科室询问创建结果
     */
    private IntentAnalysisResult createDirectInquiryResult(String query, String userId) {
        logger.info("创建直接科室询问结果 - 用户ID: {}, 查询: {}", userId, query);
        
        // 基于查询内容推断症状
        String[] symptoms = extractSymptomsFromQuery(query);
        String[] medicalTerms = symptoms; // 症状本身就是医疗术语
        
        return new ExtendedIntentAnalysisResult(
            "直接挂号", 
            0.9, 
            "用户直接询问科室挂号", 
            new String[]{query}, 
            medicalTerms,
            "medium", 
            false, 
            "direct_recommendation", 
            "直接推荐科室",
            true,  // shouldSkipSymptomCollection
            true   // directRecommendation
        );
    }
    
    /**
     * 从查询中提取症状关键词
     */
    private String[] extractSymptomsFromQuery(String query) {
        String lowerQuery = query.toLowerCase();
        java.util.List<String> symptoms = new java.util.ArrayList<>();
        
        if (lowerQuery.contains("头疼") || lowerQuery.contains("头痛")) {
            symptoms.add("头痛");
        }
        if (lowerQuery.contains("胃痛") || lowerQuery.contains("胃疼")) {
            symptoms.add("胃痛");
        }
        if (lowerQuery.contains("腹痛") || lowerQuery.contains("肚子痛")) {
            symptoms.add("腹痛");
        }
        if (lowerQuery.contains("胸痛") || lowerQuery.contains("胸口痛")) {
            symptoms.add("胸痛");
        }
        if (lowerQuery.contains("发烧") || lowerQuery.contains("发热")) {
            symptoms.add("发热");
        }
        if (lowerQuery.contains("咳嗽")) {
            symptoms.add("咳嗽");
        }
        if (lowerQuery.contains("腰痛")) {
            symptoms.add("腰痛");
        }
        
        return symptoms.isEmpty() ? new String[]{"症状询问"} : symptoms.toArray(new String[0]);
    }
    
    /**
     * 扩展的意图分析结果类
     */
    public static class ExtendedIntentAnalysisResult extends IntentAnalysisResult {
        private final String conversationStage;
        private final String nextAction;
        private final boolean shouldSkipSymptomCollection;
        private final boolean directRecommendation;
        
        public ExtendedIntentAnalysisResult(String intent, double confidence, String reason, 
                                          String[] keywords, String[] medicalTerms, String riskLevel, 
                                          boolean fullAiAnalysis, String conversationStage, String nextAction,
                                          boolean shouldSkipSymptomCollection, boolean directRecommendation) {
            super(intent, confidence, reason, keywords, medicalTerms, riskLevel, fullAiAnalysis);
            this.conversationStage = conversationStage;
            this.nextAction = nextAction;
            this.shouldSkipSymptomCollection = shouldSkipSymptomCollection;
            this.directRecommendation = directRecommendation;
        }
        
        public String getConversationStage() { return conversationStage; }
        public String getNextAction() { return nextAction; }
        public boolean isShouldSkipSymptomCollection() { return shouldSkipSymptomCollection; }
        public boolean isDirectRecommendation() { return directRecommendation; }
    }
    
    public static class IntentAnalysisResult {
        private final String intent;
        private final double confidence;
        private final String reason;
        private final String[] keywords;
        private final String[] medicalTerms;
        private final String riskLevel;
        private final boolean fullAiAnalysis;
        
        public IntentAnalysisResult(String intent, double confidence, String reason, 
                                  String[] keywords, String[] medicalTerms, String riskLevel, boolean fullAiAnalysis) {
            this.intent = intent;
            this.confidence = confidence;
            this.reason = reason;
            this.keywords = keywords;
            this.medicalTerms = medicalTerms;
            this.riskLevel = riskLevel;
            this.fullAiAnalysis = fullAiAnalysis;
        }
        
        public String getIntent() { return intent; }
        public double getConfidence() { return confidence; }
        public String getReason() { return reason; }
        public String[] getKeywords() { return keywords; }
        public String[] getMedicalTerms() { return medicalTerms; }
        public String getRiskLevel() { return riskLevel; }
        public boolean isFullAiAnalysis() { return fullAiAnalysis; }
    }
}